package xworker.javafx.scene;

import javafx.geometry.NodeOrientation;
import javafx.scene.Cursor;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.paint.Paint;
import javafx.stage.Stage;
import org.xmeta.ActionContext;
import org.xmeta.Thing;
import xworker.javafx.beans.property.PropertyFactory;
import xworker.javafx.util.JavaFXUtils;

public class SceneActions {
	static{
		PropertyFactory.regist(Scene.class, "eventDispatcherProperty", o -> {
			Scene obj = (Scene) o;
			return obj.eventDispatcherProperty();
		});
		PropertyFactory.regist(Scene.class, "cursorProperty", o -> {
			Scene obj = (Scene) o;
			return obj.cursorProperty();
		});
		PropertyFactory.regist(Scene.class, "onDragOverProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onDragOverProperty();
		});
		PropertyFactory.regist(Scene.class, "onDragDoneProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onDragDoneProperty();
		});
		PropertyFactory.regist(Scene.class, "onRotateProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onRotateProperty();
		});
		PropertyFactory.regist(Scene.class, "onSwipeUpProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onSwipeUpProperty();
		});
		PropertyFactory.regist(Scene.class, "onScrollProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onScrollProperty();
		});
		PropertyFactory.regist(Scene.class, "onZoomProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onZoomProperty();
		});
		PropertyFactory.regist(Scene.class, "onKeyTypedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onKeyTypedProperty();
		});
		PropertyFactory.regist(Scene.class, "rootProperty", o -> {
			Scene obj = (Scene) o;
			return obj.rootProperty();
		});
		PropertyFactory.regist(Scene.class, "fillProperty", o -> {
			Scene obj = (Scene) o;
			return obj.fillProperty();
		});
		PropertyFactory.regist(Scene.class, "cameraProperty", o -> {
			Scene obj = (Scene) o;
			return obj.cameraProperty();
		});
		PropertyFactory.regist(Scene.class, "onDragEnteredProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onDragEnteredProperty();
		});
		PropertyFactory.regist(Scene.class, "onDragExitedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onDragExitedProperty();
		});
		PropertyFactory.regist(Scene.class, "onDragDroppedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onDragDroppedProperty();
		});
		PropertyFactory.regist(Scene.class, "onZoomFinishedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onZoomFinishedProperty();
		});
		PropertyFactory.regist(Scene.class, "onKeyPressedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onKeyPressedProperty();
		});
		PropertyFactory.regist(Scene.class, "onInputMethodTextChangedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onInputMethodTextChangedProperty();
		});
		PropertyFactory.regist(Scene.class, "onMouseDraggedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onMouseDraggedProperty();
		});
		PropertyFactory.regist(Scene.class, "onZoomStartedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onZoomStartedProperty();
		});
		PropertyFactory.regist(Scene.class, "onSwipeDownProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onSwipeDownProperty();
		});
		PropertyFactory.regist(Scene.class, "onSwipeLeftProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onSwipeLeftProperty();
		});
		PropertyFactory.regist(Scene.class, "onMouseDragReleasedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onMouseDragReleasedProperty();
		});
		PropertyFactory.regist(Scene.class, "onMouseClickedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onMouseClickedProperty();
		});
		PropertyFactory.regist(Scene.class, "onMouseDragOverProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onMouseDragOverProperty();
		});
		PropertyFactory.regist(Scene.class, "onMouseEnteredProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onMouseEnteredProperty();
		});
		PropertyFactory.regist(Scene.class, "onMouseExitedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onMouseExitedProperty();
		});
		PropertyFactory.regist(Scene.class, "onMouseDragExitedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onMouseDragExitedProperty();
		});
		PropertyFactory.regist(Scene.class, "onMousePressedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onMousePressedProperty();
		});
		PropertyFactory.regist(Scene.class, "onScrollStartedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onScrollStartedProperty();
		});
		PropertyFactory.regist(Scene.class, "onTouchReleasedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onTouchReleasedProperty();
		});
		PropertyFactory.regist(Scene.class, "onKeyReleasedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onKeyReleasedProperty();
		});
		PropertyFactory.regist(Scene.class, "onDragDetectedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onDragDetectedProperty();
		});
		PropertyFactory.regist(Scene.class, "nodeOrientationProperty", o -> {
			Scene obj = (Scene) o;
			return obj.nodeOrientationProperty();
		});
		PropertyFactory.regist(Scene.class, "onMouseMovedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onMouseMovedProperty();
		});
		PropertyFactory.regist(Scene.class, "onScrollFinishedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onScrollFinishedProperty();
		});
		PropertyFactory.regist(Scene.class, "onRotationStartedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onRotationStartedProperty();
		});
		PropertyFactory.regist(Scene.class, "onRotationFinishedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onRotationFinishedProperty();
		});
		PropertyFactory.regist(Scene.class, "onTouchPressedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onTouchPressedProperty();
		});
		PropertyFactory.regist(Scene.class, "onSwipeRightProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onSwipeRightProperty();
		});
		PropertyFactory.regist(Scene.class, "onContextMenuRequestedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onContextMenuRequestedProperty();
		});
		PropertyFactory.regist(Scene.class, "onTouchMovedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onTouchMovedProperty();
		});
		PropertyFactory.regist(Scene.class, "onMouseReleasedProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onMouseReleasedProperty();
		});
		PropertyFactory.regist(Scene.class, "onTouchStationaryProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onTouchStationaryProperty();
		});
		PropertyFactory.regist(Scene.class, "onMouseDragEnteredProperty", o -> {
			Scene obj = (Scene) o;
			return obj.onMouseDragEnteredProperty();
		});
		PropertyFactory.regist(Scene.class, "userAgentStylesheetProperty", o -> {
			Scene obj = (Scene) o;
			return obj.userAgentStylesheetProperty();
		});
	}

	public static void init(Scene scene, Thing thing, ActionContext actionContext) {
        if(thing.valueExists("cursor")){
        	Cursor cursor = JavaFXUtils.getCursor(thing.getString("cursor"));
        	if(cursor != null) {
        		scene.setCursor(cursor);
        	}
        }
        if(thing.valueExists("nodeOrientation")) {
			scene.setNodeOrientation(NodeOrientation.valueOf(thing.getString("nodeOrientation")));
		}
	}
	
	public static Scene create(ActionContext actionContext) {
		Thing self = actionContext.getObject("self");
		Object parent = actionContext.get("parent");
		
		Parent root = self.doAction("getRoot", actionContext);
		Paint fill = self.doAction("getFill", actionContext);
		Scene scene = null;
		
		if(self.valueExists("antiAliasing")) {
			scene = new Scene(root, self.getDouble("width"), self.getDouble("height"), 
					self.getBoolean("depthBuffer"), JavaFXUtils.getSceneAntialiasing(self.getString("antiAliasing")));
		}else if(self.valueExists("width") && self.valueExists("height") &&  self.valueExists("depthBuffer")) {
			scene = new Scene(root, self.getDouble("width"), self.getDouble("height"),self.getBoolean("depthBuffer"));
		}else if(self.valueExists("width") && self.valueExists("height") && fill != null) {
			scene = new Scene(root, self.getDouble("width"), self.getDouble("height"), fill);
		}else if(self.valueExists("width") && self.valueExists("height")) {
			scene = new Scene(root, self.getDouble("width"), self.getDouble("height"));
		}else if(fill != null) {
			scene = new Scene(root, fill);
		}else {
			scene = new Scene(root);
		}
		
		init(scene, self, actionContext);
		actionContext.g().put(self.getMetadata().getName(), scene);
		
		actionContext.peek().put("parent", scene);
		for(Thing child : self.getChilds()) {
			child.doAction("create", actionContext);
		}
		
		if(parent instanceof Stage) {
			((Stage) parent).setScene(scene);
		}
		
		return scene;
	}
}
